﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Net;
using System.Diagnostics;
using System.Threading;

namespace Twitter.Tests
{
	[TestFixture]
	public class BotIntegrationFixture
	{
		[SetUp]
		public void SetUp()
		{
			if (Debugger.IsAttached)
			{
				Tracer.SetLoggingLevel(typeof(BotProcessor).Namespace, SourceLevels.Verbose);
				Tracer.AddListener(typeof(BotProcessor).Namespace, new ConsoleTraceListener());
			}

			IBotClient bot;
			IBotClient client;
			TestRun.CreateClients(out bot, out client);

			foreach (var msg in bot.Messages.GetAll())
			{
				Assert.IsTrue(bot.Messages.Delete(msg.Id));
			}
			foreach (var msg in client.Messages.GetAll())
			{
				Assert.IsTrue(client.Messages.Delete(msg.Id));
			}
			foreach (var friend in bot.Friendship.GetFriends())
			{
				Assert.IsTrue(bot.Friendship.Leave(friend));
			}
			foreach (var friend in client.Friendship.GetFriends())
			{
				Assert.IsTrue(client.Friendship.Leave(friend));
			}
		}

		[Test]
		public void ShouldWorkEndToEnd()
		{
			IBotClient bot;
			IBotClient client;
			TestRun.CreateClients(out bot, out client);

			Assert.AreEqual(0, bot.Friendship.GetFriends().Count());
			Assert.AreEqual(0, client.Friendship.GetFriends().Count());
			Assert.AreEqual(0, bot.Messages.GetAll().Count());
			Assert.AreEqual(0, client.Messages.GetAll().Count());

			Assert.IsTrue(client.Friendship.Follow(TestRun.BotScreenName));

			Assert.That(bot.Friendship.GetFollowers().Contains(TestRun.ClientScreenName));
			Assert.IsFalse(bot.Friendship.GetFriends().Contains(TestRun.ClientScreenName));

			MockBot botProc = new MockBot();
			BotProcessor processor = new BotProcessor(bot, botProc, botProc);
			processor.Run();

			// Should make friends
			Assert.That(bot.Friendship.GetFriends().Contains(TestRun.ClientScreenName));
			Assert.That(client.Friendship.GetFriends().Contains(TestRun.BotScreenName));
			Assert.AreEqual("hello", client.Messages.GetAll().First().Text);

			Thread.Sleep(100);

			client.Messages.Send(TestRun.BotScreenName, "bye");

			processor.Run(false);

			// Should process messages
			var messages = client.Messages.GetAll().ToList();
			Assert.AreEqual("bye-ack", client.Messages.GetAll().Last().Text);
		}

		class MockBot : IGreeter, IMessageProcessor
		{
			public void Greet(IBotClient client, string newFriend)
			{
				client.Messages.Send(newFriend, "hello");
			}
            public bool CanProcess(Message message)
            {
                return true;
            }

			public RunNextProcessor Process(IBotClient client, Message message)
			{
				client.Messages.Send(message.Sender.ScreenName, message.Text + "-ack");
				return RunNextProcessor.Yes;
			}
		}
	}
}
